﻿using System;
using System.Collections.Generic;
using System.Text;
using XDesigner.Development.Dom ;
using System.Windows.Forms ;
using System.Drawing ;
using System.Collections;

namespace XDesigner.Development.Controls
{
    public class TreeViewHelper
    {
        private const string DirectoryFlag = "DirectoryFlag";
        private const string MissFlag = "MissFlag";
        public static void Fill(ImageList imgList, SolutionInfo sln)
        {
            if (imgList.Images.ContainsKey(DirectoryFlag) == false)
            {
                Bitmap bmp = DevResources.directory;
                bmp.MakeTransparent();
                imgList.Images.Add(DirectoryFlag, bmp );
            }
            if (imgList.Images.ContainsKey(MissFlag) == false)
            {
                imgList.Images.Add(MissFlag, MissIcon);
            }
            string ext = System.IO.Path.GetExtension(sln.FileName);
            AddImage(imgList, ext);
            foreach (SourceFileInfo file in sln.Files)
            {
                AddImage( imgList , System.IO.Path.GetExtension( file.FileName ));
            }
            foreach (ProjectInfo prj in sln.Projects)
            {
                AddImage(imgList, prj.Extension);
                foreach (SourceFileInfo file in prj.Files)
                {
                    ext = System.IO.Path.GetExtension(file.FileName);
                    AddImage(imgList, ext);
                }
            }
        }

        public static void Fill( TreeView tvw, SolutionInfo sln)
        {
            TreeNode rootNode = new TreeNode(sln.Name + "("
                + string.Format(DevStrings.Projects_Num, sln.Projects.Count)
                + ")");
            rootNode.Tag = sln;
            rootNode.ImageKey = System.IO.Path.GetExtension( sln.FileName );
            rootNode.SelectedImageKey = rootNode.ImageKey;
            tvw.Nodes.Add(rootNode);
            if (sln.Files.Count > 0)
            {
                TreeNode filesNode = new TreeNode("Files");
                filesNode.ImageKey = DirectoryFlag;
                filesNode.SelectedImageKey = filesNode.ImageKey;
                rootNode.Nodes.Add(filesNode);
                foreach (SourceFileInfo file in sln.Files)
                {
                    TreeNode fileNode = new TreeNode(file.FileName);
                    fileNode.ImageKey = System.IO.Path.GetExtension(file.FileName);
                    fileNode.SelectedImageKey = fileNode.ImageKey;
                    fileNode.Tag = file;
                    filesNode.Nodes.Add(fileNode);
                }
            }
            foreach (ProjectInfo prj in sln.Projects)
            {
                TreeNode prjNode = new TreeNode(prj.Name);
                rootNode.Nodes.Add(prjNode);
                Fill(prjNode, prj);
                SortTreeNode(prjNode.Nodes);
            }
            SortTreeNode(rootNode.Nodes);
        }

        public static void Fill(TreeNode rootNode, ProjectInfo prj)
        {
            rootNode.Tag = prj;
            rootNode.Text = prj.Name + "(" + string.Format( DevStrings.TotalFiles_Num , prj.Files.Count ) + ")";
            rootNode.ToolTipText = prj.ProjectFileName;
            if (System.IO.File.Exists(prj.ProjectFileName))
            {
                rootNode.ImageKey = prj.Extension;
            }
            else
            {
                rootNode.ImageKey = MissFlag;
            }
            rootNode.SelectedImageKey = rootNode.ImageKey;
            Fill(rootNode, prj.Files);
        }

        private static void SortTreeNode(TreeNodeCollection nodes)
        {
            if (nodes.Count > 1)
            {
                ArrayList list = new ArrayList(nodes);
                list.Sort(new TreeNodeComparer());
                nodes.Clear();
                foreach (TreeNode node in list)
                {
                    nodes.Add(node);
                    if (node.Nodes.Count > 1)
                    {
                        SortTreeNode(node.Nodes);
                    }
                }
            }
            else if( nodes.Count == 1 )
            {
                if (nodes[0].Nodes.Count > 1)
                {
                    SortTreeNode(nodes[0].Nodes);
                }
            }

        }

        private class TreeNodeComparer : System.Collections.IComparer
        {

            #region IComparer 成员

            public int Compare(object x, object y)
            {
                TreeNode node1 = (TreeNode)x;
                TreeNode node2 = (TreeNode)y;
                bool dir1 = node1.ImageKey == DirectoryFlag;
                bool dir2 = node2.ImageKey == DirectoryFlag;
                if (dir1 == dir2)
                {
                    return string.Compare(node1.Text, node2.Text, true);
                }
                else
                {
                    if (dir1)
                    {
                        return -1;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }

            #endregion
        }

        public static void Fill(TreeNode rootNode, FileElementList files)
        {
            foreach (SourceFileInfo file in files)
            {
                bool isDir = false;
                string fileName = file.FileName;
                if (fileName.IndexOf("VBConverter") >= 0 ) 
                {
                    System.Console.WriteLine("");
                }
                if (fileName.EndsWith("\\"))
                {
                    fileName = fileName.Substring(0, fileName.Length - 1);
                    isDir = true;
                }
                string[] pathItems = fileName.Split('\\');
                TreeNode currentNode = rootNode;
                for (int iCount = 0; iCount < pathItems.Length ; iCount++)
                {
                    string pathItem = pathItems[iCount];
                    bool find = false;
                    foreach (TreeNode node in currentNode.Nodes)
                    {
                        if (string.Compare(node.Text, pathItem, true) == 0)
                        {
                            currentNode = node;
                            find = true;
                            break;
                        }
                    }
                    if (find == false)
                    {
                        TreeNode newNode = new TreeNode(pathItem);
                        if (pathItem.Length == 0)
                        {
                            System.Console.WriteLine("");
                        }
                        if (iCount < pathItem.Length - 1)
                        {
                            newNode.ImageKey = DirectoryFlag ;
                            newNode.SelectedImageKey = newNode.ImageKey;
                        }
                        currentNode.Nodes.Add(newNode);
                        currentNode = newNode;
                    }
                }//for
                currentNode.Tag = file;
                if (isDir || file.Style == FileStyle.Directory )
                {
                    currentNode.ImageKey = DirectoryFlag;
                }
                else if (System.IO.File.Exists(file.FullFileName ))
                {
                    currentNode.ImageKey = System.IO.Path.GetExtension(fileName);
                }
                else
                {
                    currentNode.ImageKey = MissFlag;
                }
                currentNode.SelectedImageKey = currentNode.ImageKey;
            }//foreach
        }

        
        private static Dictionary<string, Image> extensionIcons = new Dictionary<string, Image>();

        private static void AddImage(ImageList imgList, string extension)
        {
            if (extension == null)
            {
                return ;
            }
            if (imgList.Images.ContainsKey(extension) == false)
            {
                string name = extension ;
                if( name.StartsWith("."))
                {
                    name = name.Substring( 1 ).Trim().ToLower();
                    object obj = DevResources.ResourceManager.GetObject(name);
                    if (obj != null && obj is System.Drawing.Image )
                    {
                        System.Drawing.Image img = (System.Drawing.Image)obj;
                        if (img is Bitmap)
                        {
                            Bitmap bmp = (Bitmap)img;
                            bmp.MakeTransparent(Color.Red);
                        }
                        imgList.Images.Add(extension, img);
                        return;
                    }
                }
                XDesigner.WinForms.Native.FileExtensionInfo info = new WinForms.Native.FileExtensionInfo("a" + extension );
                Icon icon = info.DefaultIcon;
                if (icon != null)
                {
                    if (icon.Size != imgList.ImageSize)
                    {
                        Icon icon2 = new Icon(icon, imgList.ImageSize);
                        icon.Dispose();
                        icon2 = icon;
                    }
                    Bitmap bmp = icon.ToBitmap();
                    if (bmp.Width != imgList.ImageSize.Width && bmp.Height != imgList.ImageSize.Height)
                    {
                        Image img2 = bmp.GetThumbnailImage(16, 16, delegate() { return false; }, IntPtr.Zero);
                        imgList.Images.Add(extension, img2);
                        bmp.Dispose();
                    }
                    else
                    {
                        imgList.Images.Add(extension, bmp);
                    }
                    icon.Dispose();
                }
                else
                {
                    if (_DefaultIcon == null)
                    {
                        _DefaultIcon = DevResources.DefaultFile;
                        _DefaultIcon.MakeTransparent();
                    }
                    imgList.Images.Add(extension, _DefaultIcon );
                }
            }
        }
        private static Bitmap _DefaultIcon = null;

        private static Bitmap _MissIcon = null;
        public static Bitmap MissIcon
        {
            get
            {
                if (_MissIcon == null)
                {
                    _MissIcon = DevResources.miss;
                    _MissIcon.MakeTransparent();
                }
                return _MissIcon;
            }
        }

        public static ImageList CreateImageList(string[] extensions)
        {
            ImageList result = new ImageList();
            XDesigner.WinForms.Native.FileExtensionInfo info = new WinForms.Native.FileExtensionInfo( );
            foreach (string ext in extensions)
            {
                if (result.Images.ContainsKey(ext))
                {
                    continue;
                }
                Image img = null;
                if (extensionIcons.ContainsKey(ext))
                {
                    img = extensionIcons[ext];
                }
                else
                {
                    info.Reset("a" + ext);
                    Icon icon = info.DefaultIcon;
                    if (icon != null)
                    {
                        img = icon.ToBitmap();
                        extensionIcons[ext] = img;
                    }
                }
                result.Images.Add(ext, img);
            }//foreach
            return result;
        }
    }
}
